﻿using System;
using System.Collections.Generic;
using System.IO;
using Jsdl.Generators;

namespace Jsdl
{
    public class Program
	{       
        public static void Main(string[] args)
		{
			// FOR TESTING ONLY
			//var json = File.ReadAllText(@"Path/To/Json");
			var gen = CodeGenerator.Create("Csharp");
			//var code = gen.GenerateServiceClientCodeFromJson(json);
            var code = gen.GenerateServiceClientCodeFromUrl("http://localhost:4338/JsdlServices/DataService?operation=Jsdl", "Abc", "Def");

            if (args.Length > 0)
			{
				var arguments = ParseArguments(args);

				var outputType = GetArgument(arguments, "--type", "Csharp");
                var className = GetArgument(arguments, "--class", "UnknownServiceClient");
                var namespaceName = GetArgument(arguments, "--namespace", "UnknownNamespace");

                var outputFile = GetArgument(arguments, "--output", null);
                var jsdl = GetArgument(arguments, "--jsdl", null);

				if (jsdl != null && outputFile != null)
				{
					var generator = CodeGenerator.Create(outputType);

                    foreach (var pair in arguments)
					{
						var prop = generator.GetType().GetProperty(pair.Key.Substring(2));
						if (prop != null)
							prop.SetValue(generator, ConvertValue(pair.Value, prop.PropertyType)); 
					}

					try
					{
						var output = jsdl.StartsWith("http://") || jsdl.StartsWith("https://")
							? generator.GenerateServiceClientCodeFromUrl(jsdl, className, namespaceName)
							: generator.GenerateServiceClientCodeFromJson(File.ReadAllText(jsdl), className, namespaceName);

						File.WriteAllText(outputFile, output);
					}
					catch (Exception ex) 
					{
						Console.WriteLine("Exception: " + ex.Message);
					}
				}
				else
					Console.WriteLine("Exception: '--jsdl' and '--output' argument must be set!");
			}
			else
			{
				Console.WriteLine("Arguments: ");

				Console.WriteLine("--jsdl [URL or path]");
				Console.WriteLine("--output [path]");
				Console.WriteLine("--type (TypeScript|Csharp), default: Csharp");

				Console.WriteLine("--class [web service client class name], default: UnknownServiceClient");
				Console.WriteLine("--type [web service client class namespace], default: UnknownNamespace");

				Console.WriteLine();
				Console.WriteLine();

				Console.WriteLine("TypeScript arguments");
				Console.WriteLine("--GenerateServiceClass (true|false), default: false");
				Console.WriteLine("--GenerateBaseUrl (true|false), default: true");
				Console.WriteLine("--GenerateInterfaces (true|false), default: true");
				Console.WriteLine("--UseKnockoutJs (true|false), default: true");
				Console.WriteLine("--LibraryPath [path to typescript libraries], default: libs");

				Console.WriteLine();
				Console.WriteLine("Csharp arguments");
				Console.WriteLine("--UseMyToolkit (true|false), default: false");
			}
		}

		private static object ConvertValue(string value, Type type)
		{
			if (type == typeof(string))
				return value;
			if (type == typeof(bool))
				return bool.Parse(value);
			if (type == typeof(int))
				return int.Parse(value);
			if (type == typeof(double))
				return double.Parse(value);
			if (type == typeof(decimal))
				return decimal.Parse(value);
			if (type == typeof(float))
				return float.Parse(value); 

			throw new NotImplementedException("Could not convert argument to desired type");
		}

        private static IDictionary<string, string> ParseArguments(string[] args)
        {
            var dictionary = new Dictionary<string, string>();
			string key = null; 
			foreach (var arg in args)
			{
				if (key == null)
					key = arg;
				else
				{
                    dictionary.Add(key, arg);
					key = null; 
				}
			}
            return dictionary; 
        }

		private static string GetArgument(IDictionary<string, string> arguments, string key, string defaultValue)
		{
            if (arguments.ContainsKey(key))
                return arguments[key];
			return defaultValue;
		}
	}
}
